import graph.BarGraph;

import java.util.Iterator;
import java.util.Vector;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import charts.DriftChart;
import charts.ErrorChart;
import summary.GradientStatistics;
import summary.InstantData;
import summary.InstantStatistics;
import summary.NodeData;
import summary.ReferenceStatistics;


public class Summary{
	
	public Summary(int numNodes, Vector<InstantData> data, Vector<InstantStatistics> statistics,ReferenceStatistics refStatistics,GradientStatistics gradientStatistics) {
		createErrorChart(statistics);
		createRateMultiplierChart(data,numNodes);
	    createRootSkewsChart(refStatistics);
	    createGradientChart(gradientStatistics);
	}
	
	private void createRateMultiplierChart(Vector<InstantData> statistics, int numNodes) {
		XYSeries[] series = new XYSeries[numNodes];
		XYSeriesCollection dataset = new XYSeriesCollection();
		
		for (int i=0; i< series.length; i++){
			series[i] = new XYSeries("node "+ (i+1));	
			dataset.addSeries(series[i]);
		}	
						
		for (Iterator<InstantData> iterator = statistics.iterator(); iterator.hasNext();) {
			InstantData results = (InstantData) iterator.next();
			Vector<NodeData> nodes = results.getData();
				
			for (Iterator<NodeData> iterator2 = nodes.iterator(); iterator2.hasNext();) {
				NodeData data = (NodeData) iterator2.next();
				series[(int) (data.id-1)].add(results.second,1000000.0f*Float.intBitsToFloat((int) data.skew));
			}				
		}	
		
		
		XYSeriesCollection newDataSet = new XYSeriesCollection();
		
//		newDataSet.addSeries(dataset.getSeries(1));
		
		for (int i = 1; i < dataset.getSeriesCount(); i++) {
//			if((i+1)%5==0)
				newDataSet.addSeries(dataset.getSeries(i));
		}
		
		DriftChart graph = new DriftChart(newDataSet);
//		graph.setDataRange(0, 10000, -5, 1);
		
	}

	private void createErrorChart(Vector<InstantStatistics> statistics) {
	    
		final XYSeries global = new XYSeries("Max. Global");
		final XYSeries avgGlobal = new XYSeries("Avg. Global");
		final XYSeries local = new XYSeries("Max. Local");
		final XYSeries avgLocal = new XYSeries("Avg. Local");
		
		XYSeriesCollection globalDataset = new XYSeriesCollection();
		XYSeriesCollection localDataset = new XYSeriesCollection();
		globalDataset.addSeries(global);
		globalDataset.addSeries(avgGlobal);
		localDataset.addSeries(local);
		localDataset.addSeries(avgLocal);
		
		for (Iterator<InstantStatistics> iterator = statistics.iterator(); iterator.hasNext();) {
			InstantStatistics data = (InstantStatistics) iterator.next();

			global.add(data.second,data.maxGlobalSkew);
			avgGlobal.add(data.second,data.avgGlobalSkew);
			local.add(data.second,data.maxLocalSkew);
			avgLocal.add(data.second,data.avgLocalSkew);	
		}		
		
		new ErrorChart("Global Synchronization Error",globalDataset);
		new ErrorChart("Local Synchronization Error",localDataset);
	}	
		
	private void createRootSkewsChart(ReferenceStatistics refStatistics) {
      
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        
        for(int i=0;i<refStatistics.getReferenceSkews().length;i++){
        	long skew = refStatistics.getReferenceSkews()[i];
        	dataset.setValue(skew, "Skew", Integer.toString(i+1));	
        }
        
        new BarGraph("Maximum Error to the Reference Node", "Node identifier", "Error (microseconds)", dataset);
	}	
	
	private void createGradientChart(GradientStatistics gradientStatistics) {
	      
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        
        for(int i=0;i<gradientStatistics.getMaxLocalSkews().length;i++){
        	long skew = gradientStatistics.getMaxLocalSkews()[i];
        	dataset.setValue(skew, "Skew", Integer.toString(i+1));	
        }
        
        new BarGraph("Maximum Local Skew", "Node identifier", "Error (microseconds)", dataset);
	}
}
